using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;

namespace LS
{
    public class UnityComponentReferenceHolder : MonoBehaviour
    {
        [SerializeField]
        private Component m_Reference = null;

        private bool m_AutoRegistInRuntime = true;

        [Tooltip("填写不超过62个字符（超过62后将只使用前62个字符）")]
        [StringMaxLength(62)]
        [SerializeField]
        private string m_ReferenceKey = null;

        [SerializeField]
        [ReadOnlyOnInspector]
        private int m_ReferenceInstanceId = 0;

        private bool m_Unregisted = false;

        public string ReferenceKey
        {
            get
            {
                return m_ReferenceKey;
            }
        }

        public int ReferenceInstanceId
        {
            get
            {
                return m_ReferenceInstanceId;
            }
        }

        public Component Reference
        {
            get
            {
                return m_Reference;
            }
        }
        private void Awake()
        {
            if (!string.IsNullOrEmpty(m_ReferenceKey) && m_ReferenceKey.Length > 62)
            {
                m_ReferenceKey = m_ReferenceKey.Substring(0, 62);
            }

            if (m_Reference != null)
                SetUp(m_Reference);
        }

        private void Start()
        {
            if (m_Reference != null && m_AutoRegistInRuntime)
            {
                RegistHolder(this);
            }
        }

        private void OnDestroy()
        {
            if (!m_Unregisted)
            {
                UnityComponentForDOTSReferences.Instance.UnregistReference(this);
            }
        }

        public void SetUp(Component component)
        {
            this.m_Reference = component;
            m_ReferenceInstanceId = component.GetInstanceID();
        }

        public void OnRegist()
        {
            
        }

        public void OnUnregist()
        {
            m_Unregisted = true;
        }

        public bool Equal(int instanceId)
        {
            if (this.m_ReferenceInstanceId == 0)
            {
                return false;
            }

            return instanceId == this.m_ReferenceInstanceId;
        }

        public bool Equal(Component component)
        {
            if (component == null)
            {
                return false;
            }

            if (component is UnityComponentReferenceHolder)
            {
                return (component as UnityComponentReferenceHolder).Equal(this.m_ReferenceInstanceId);
            }
            else
            {
                return component == this.m_Reference;
            }
        }

        public static UnityComponentReferenceHolder GetOrAddHolder(Component component, string instanceKeyOnAdd = null)
        {
            if (component is UnityComponentReferenceHolder)
            {
                return component as UnityComponentReferenceHolder;
            }

            var holder = component.GetComponents<UnityComponentReferenceHolder>().First(c => c.Equal(component));
            if (holder == null)
            {
                holder = component.AddComponent<UnityComponentReferenceHolder>();
                holder.m_ReferenceKey = instanceKeyOnAdd;
                holder.SetUp(component);
            }
            return holder;
        }

        public static int RegistHolder(Component component)
        {
            return UnityComponentForDOTSReferences.Instance.RegistReference(component);
        }
    }
}
